#include "mainwindow.h"

//用于移动球的宏方法
#define Move(ball)\
QPoint p2=QPoint(ball.x,ball.y);\
    QPixmap pix;\
    switch(ball.type){\
    case 0:{pix.load("://src/picture/1.jpg");break;}\
    case 1:{pix.load("://src/picture/2.jpg");break;}\
    case 2:{pix.load("://src/picture/3.jpg");break;}\
    case 3:{pix.load("://src/picture/4.jpg");break;}\
    case 4:{pix.load("://src/picture/5.jpg");break;}\
    case 5:{pix.load("://src/picture/6.jpg");break;}\
    case 6:{pix.load("://src/picture/7.jpg");break;}\
    default:{pix.load("://src/picture/8.jpg");break;}\
}\
    paint.drawPixmap(ball.x-ball.size,ball.y-ball.size,2*ball.size,2*ball.size,pix);\

// 构造函数
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent){
    // 初始化必要内容
    this->initUI();                    //初始化界面
    this->iniSignals();                //按钮与函数的信号连接
    this->status=STOP;                 //游戏开始前状态为STOP
    this->setMouseTracking(true);      //开启鼠标移动事件

   /* for (BallType ballType = BallType1; ballType <= BallType8; (ballType)+1) {
        // 假设音效资源文件路径为 ":/sounds/ballTypeX.wav"，其中 X 是球的类型
        QString soundFile = QString(":/src/music/1%1.wav").arg(static_cast<int>(ballType) + 1);
        QUrl soundUrl(soundFile);
        QMediaPlayer *player = new QMediaPlayer(this);
        player->setMedia(QMediaContent(soundUrl));
        ballSounds[ballType] = player;
    }*/
    // 数据初始化
    this->startTimer(25);              //启动计时器并设置帧率为20ms
    this->nextBall();                  //生成第一个球

    // 设置背景色
    QPalette pal;
    pal.setColor(QPalette::Window, Qt::white);
    this->setAutoFillBackground(true);
    this->setPalette(pal);

    // 计分
    this->q = new QLabel(this);
    this->str=QString("score:%1").arg(gamescore);
    this->q->setText(str);
    this->q->setStyleSheet("color: black");
    this->q->resize(WIDTH,TOPLINE);

    // 计分字体设置
    QFont ft1;
    ft1.setPointSize(40);
    this->q->move(0,5);
    this->q->setFont(ft1);
    this->q->hide();
}

// 析构函数
MainWindow::~MainWindow(){
    delete Start;
    delete Rank;
    delete Exit;
    delete Back;
    delete Pause;
    delete Finish;
    delete q;
    delete Win;


}

// Setbutton 设置按钮(重载1):设置按钮并设置按钮文字
auto MainWindow::setButton(QPushButton *B,int width,int height, int x, int y, QString str)->void{
    const int FSIZE=WIDTH/21;             //按钮的字体大小
    QFont font;
    font.setPointSize(FSIZE);
    font.setWeight(QFont::Bold);          //字体粗细
    B->resize(width,height);              //按钮大小
    B->setText(str);                      //设置按钮文字
    B->move(x,y);                         //将按钮放在(x,y)处
    B->setFont(font);
}

// Setbutton 设置按钮（重载2）:设置按钮并设置按钮图片
auto MainWindow::setButton(QPushButton *B, int width, int height, int x, int y, int a)->void{
    B->move(x,y);                         //将按钮放在(x,y)处
    if(a==1){
        B->setStyleSheet("border-image:url(:/src/picture/start.jpg);");
    }
    else if(a==2){
        B->setStyleSheet("border-image:url(:/src/picture/rules.jpg);");
    }
    else if(a==3){
        B->setStyleSheet("border-image:url(:/src/picture/arrow.jpg);");

    }
    else if(a==4){
        B->setStyleSheet("border-image:url(:/src/picture/arrow.jpg);");

    }
    else if(a==5){
        B->setStyleSheet("border-image:url(:/src/picture/lose.jpg);");
        B->resize(width,height);
    }else if(a==6){
        B->setStyleSheet("border-image:url(:src/picture/win.jpg);");
        B->resize(width,height);
    }
}

// onRestart 重新开始游戏
auto MainWindow::onRestart()->void {
    qApp->quit();
    QProcess::startDetached(qApp->applicationFilePath(), QStringList());
}

// initUI 初始化界面
auto MainWindow::initUI()->void{
    // 窗口属性设置
    this->setFixedSize(WIDTH,HEIGHT);     // 固定窗口大小（不能改变）
    this->setWindowTitle("合成SKZ");       // 设置窗口标题

    // 按钮的宽和高
    const int BWIDTH{WIDTH/3};
    const int BHEIGHT{HEIGHT/9};

    // 生成相应按钮并挂载到对象树上
    this->Start=new QPushButton(this);
    this->Win=new QPushButton(this);
    this->Rank=new QPushButton(this);
    this->Exit=new QPushButton(this);
    this->Back=new QPushButton(this);
    this->Pause=new QPushButton(this);
    this->Finish=new QPushButton(this);
    this->maxPicture=new QPushButton(this);

    // 设置按钮的位置和大小
    this->setButton(Start,BWIDTH,BHEIGHT,146,BHEIGHT*4.59,1);
    this->setButton(Rank,BWIDTH,BHEIGHT,146,BHEIGHT*5.15,2);
    this->setButton(Exit,BWIDTH,BHEIGHT,146,BHEIGHT*5.65,3);
    this->setButton(Back,BWIDTH,BHEIGHT,BWIDTH*1.2,BHEIGHT*7,4);
    this->setButton(Pause,40,40,WIDTH-45,5,"||");
    this->setButton(Finish,BWIDTH,BHEIGHT*2,220,BHEIGHT*4,5);
    this->setButton(Win,BWIDTH,BHEIGHT*2,220,BHEIGHT*4,6);

    //隐藏"返回"、"暂停"按钮、“完成”按钮和“胜利”按钮
    this->Back->hide();
    this->Pause->hide();
    this->Finish->hide();
    this->Win->hide();

    //移动图片位置
    this->maxPicture->move(WIDTH-45,45);
    this->maxPicture->resize(40,40);
    this->maxPicture->setEnabled(false);

    //隐藏图片
    this->maxPicture->hide();
}

// showbuttons 控制界面三个按钮的显示
auto MainWindow::showButtons(bool aa)->void{
    if (aa==true){
        this->Start->show();
        this->Rank->show();
        this->Exit->show();
        this->maxPicture->show();
    }else{
        this->Start->hide();
        this->Rank->hide();
        this->Exit->hide();
        this->maxPicture->hide();
    }
}

// StartGame 开始游戏
auto MainWindow::startGame([[maybe_unused]]bool ok)->void{
    this->q->show();
    this->status=START;         //设置游戏状态为START
    this->showButtons(false);   //隐藏初始界面的按钮
    this->Pause->show();        //显示暂停按钮
    this->Pause->raise();       //上层显示
    this->maxPicture->show();   //显示当前最大头像按钮
}

// showscore 查看规则
void MainWindow::showScore(){
    this->status=SHOW1;
    this->showButtons(false);
    this->Back->show();
}

// back 返回
auto MainWindow::back()->void{
    this->status=SHOW1;
    this->showButtons(true);
    this->Back->hide();
    this->onRestart();
}

// gamepause 游戏暂停
auto MainWindow::gamePause()->void{
    int ret {QMessageBox::information(0,"info",QStringLiteral("游戏暂停"),QStringLiteral("继续游戏"),QStringLiteral("返回菜单"),"",1)};
    if (ret==0){                //继续游戏
        this->status=START;     //设置游戏状态为START
    }else if (ret==1){          //返回菜单
        this->status=CLEAR;     //清屏
        this->update();         //重新绘制
        this->showButtons(true);//返回菜单
        this->Pause->hide();    //隐藏暂停按钮
        this->status=STOP;      //停止游戏
        this->onRestart();
    }
}

// gamefinish 游戏结束
auto MainWindow::gameFinish()->void{
    this->Finish->hide();        //隐藏结束按钮
    this->status=CLEAR;          //清屏
    this->update();              //重新绘制
    this->showButtons(true);     //返回菜单
    this->status=STOP;           //重置
}

// gamewin 游戏胜利
auto MainWindow::gameWin()->void{
    this->status=WIN;            //游戏胜利
    this->onRestart();           //重新开始游戏
}

// iniSignals 信号连接
auto MainWindow::iniSignals()->void{
    //退出按钮
    connect(Exit,&QPushButton::clicked,this,&MainWindow::close);

    //开始按钮
    connect(Start,&QPushButton::clicked,this,&MainWindow::startGame);

    //积分按钮
    connect(Rank,&QPushButton::clicked,this,&MainWindow::showScore);

    //返回按钮
    connect(Back,&QPushButton::clicked,this,&MainWindow::back);

    //暂停按钮
    connect(Pause,&QPushButton::clicked,this,&MainWindow::gamePause);

    //结束按钮
    connect(Finish,&QPushButton::clicked,this,&MainWindow::gameFinish);

    //胜利按钮
    connect(Win,&QPushButton::clicked,this,&MainWindow::gameWin);
}

// nextBall 下一个球初始化
auto MainWindow::nextBall()->void{
    //随机生成下一个球的种类
    //srand((unsigned)time(NULL));
   // this->unfallingBall.type=rand()%4;
    this->unfallingBall.type=QRandomGenerator::global()->bounded(4);

    //根据种类设置大小、质量和颜色
    this->unfallingBall.initball(unfallingBall.type);
    int x1{};

    //判断生成的球是否出界，并设置其坐标
    if (mouse.x()<unfallingBall.size){
        x1=unfallingBall.size;
    }else if (mouse.x()>WIDTH-unfallingBall.size) {
        x1=WIDTH-unfallingBall.size;
    }else {
        x1=mouse.x();
    }
    this->unfallingBall.x=this->unfallingBall._x=x1;
    this->unfallingBall.y=this->unfallingBall._y=5+this->unfallingBall.size;
}

// paintEvent 画图事件
auto MainWindow::paintEvent(QPaintEvent *event)->void{
    if(status==STOP ){
        QPainter p{this};
        p.drawPixmap(0,0,WIDTH,HEIGHT,QPixmap("://src/picture/beijing.jpg"));
    }
    if (status==START){
        QPainter paint{this};
        paint.drawPixmap(0,0,this->width(),TOPLINE+25,QPixmap("://src/picture/line.png"));

        //清屏
        switch(this->background){
            case BACKGROUND::NORMAL:
                paint.drawPixmap(0,TOPLINE+25,this->width(),this->height()-TOPLINE-25,QPixmap("://src/picture/beijing.jpg"));
                break;
            case BACKGROUND::TYPE1:
                this->maxPicture->setStyleSheet("border-image:url(://src/picture/1.jpg);");
                break;
            case BACKGROUND::TYPE2:
                this->maxPicture->setStyleSheet("border-image:url(://src/picture/2.jpg);");
                break;
            case BACKGROUND::TYPE3:
                this->maxPicture->setStyleSheet("border-image:url(://src/picture/3.jpg);");
                break;
            case BACKGROUND::TYPE4:
                this->maxPicture->setStyleSheet("border-image:url(://src/picture/4.jpg);");
                break;
            case BACKGROUND::TYPE5:
                this->maxPicture->setStyleSheet("border-image:url(://src/picture/5.jpg);");
                break;
            case BACKGROUND::TYPE6:
                this->maxPicture->setStyleSheet("border-image:url(://src/picture/6.jpg);");
                break;
            case BACKGROUND::TYPE7:
                this->maxPicture->setStyleSheet("border-image:url(://src/picture/7.jpg);");
                break;
            case BACKGROUND::TYPE8:
                this->maxPicture->setStyleSheet("border-image:url(://src/picture/8.jpg);");
                break;
        }
        if(this->background!=BACKGROUND::NORMAL){
            paint.drawPixmap(0,TOPLINE+25,this->width(),this->height()-TOPLINE-25,QPixmap("://src/picture/beijing.jpg"));
        }
        paint.setRenderHint(QPainter::Antialiasing); //设置抗锯齿
        Move(unfallingBall)                          //调用Move宏移动未下落的球
        for (int i=0;i<balls.size();i++){            //遍历所有球
            Move(balls[i])
        }
    }else if (status==CLEAR){                        //清屏
        QPainter paint(this);
        paint.setBrush(QBrush(Qt::white,Qt::SolidPattern));
        paint.drawRect(QRect(0,0,WIDTH,HEIGHT));
        paint.drawPixmap(0,0,QPixmap("://src/picture/test3.png"));
    }else if (status==SHOW1){                        //清屏
        QPainter paint(this);
        paint.drawPixmap(0,0,this->width(),this->height()/3,QPixmap("://src/picture/rules_new.png"));
    }else if (status==BOOM){                         //清屏
        QPainter paint(this);
        paint.drawPixmap(int(X0),int(Y0),QPixmap("://src/picture/test3.png"));
    }else if (status==WIN){                           //清屏
        QPainter paint(this);
        QPixmap pix(":/src/picture/win.jpg");
        pix.scaled(500,250);
        paint.drawPixmap(0,0,pix);
        /*QString soundFilePath = QCoreApplication::applicationDirPath() + "/Users/liyidan/WatermelonGame/src/music/win.wav";
        QSoundEffect soundEffect;
        soundEffect.setSource(QUrl::fromLocalFile(soundFilePath));
        soundEffect.setVolume(1.0); // 注意：音量通常是0.0到1.0之间的浮点数
        soundEffect.play();*/


        //QSound::play(":/src/music/win.wav");
        QMediaPlayer *winmusic=new QMediaPlayer(this);
        winmusic->setMedia(QUrl("qrc:/src/music/win.wav"));
        winmusic->setVolume(50);
        winmusic->play();
        Back->show();

    }
}

// mouseMoveEvent 鼠标移动事件
auto MainWindow::mouseMoveEvent(QMouseEvent *event)->void{
    if (status==START){
        mouse=event->pos();
        //鼠标出界则不移动球
        if (mouse.x()<unfallingBall.size||mouse.x()>WIDTH-unfallingBall.size) {
            return;
        }
        //鼠标出界则将边界作为球的坐标
        int x1{};
        if (mouse.x()<unfallingBall.size) {
            x1=unfallingBall.size;
        }else if (mouse.x()>WIDTH-unfallingBall.size) {
            x1=WIDTH-unfallingBall.size;
        }else {
            x1=mouse.x();
        }
        //更新未下落球的坐标和鼠标的坐标
        this->unfallingBall.x=x1;
        mouse=event->pos();
        this->update();      //触发paintEvent事件
    }
}

// mousePressEvent 鼠标按下事件
auto MainWindow::mousePressEvent(QMouseEvent *event)->void{
    if (status==START){
        if(event->button() == Qt::LeftButton&&this->time1>=0){
            this->unfallingBall.vy=5;                  //下落速度
            this->unfallingBall.ay=1;                  //重力场加速度
            this->balls.push_back(unfallingBall);      //将下落的球存入数组balls
            this->time1=clock();                       //鼠标按下后一段时间后再生成新球
            this->unfallingBall.y=-100;
        }
    }
}

// timerEvent 计时器事件
auto MainWindow::timerEvent(QTimerEvent *event)->void{
    if (this->status==STOP){
        return;
    }
    if (clock()-this->time1>CLOCKS_PER_SEC&&this->time1!=0){
        this->time1=0;
        this->nextBall();
    }
    this->moveCoordinate();
    this->update();
}

// movecoordinate 根据球当前的速度与碰撞状态改变所有球的坐标
auto MainWindow::moveCoordinate()->void{
    for (int i=0;i<this->balls.size();i++){
        this->balls[i].vx+=this->balls[i].ax;
        this->balls[i].vy+=this->balls[i].ay;
        this->balls[i]._x=this->balls[i].x;
        this->balls[i]._y=this->balls[i].y;
        this->balls[i].x+=this->balls[i].vx;
        this->balls[i].y+=this->balls[i].vy;
        this->collideWall(i);
    }
    this->collision();    //碰撞
    for (int i=0;i<balls.size();i++){
        this->collideWall(i);
    }
    for (int i=0;i<balls.size();i++){
        if(this->balls[i].type==9){
            QPainter paint(this);
            paint.drawPixmap(0,0,QPixmap(":/res/win.png"));
        }
    }
}

// collideWall 判断是否撞墙并改变速度方向
auto MainWindow::collideWall(int i)->void{
    //撞右边的墙
    if (this->balls[i].x>=this->WIDTH-this->balls[i].size){
        this->balls[i].x=this->WIDTH-this->balls[i].size;//防止速度过快穿过墙
        this->balls[i].vx=-this->balls[i].vx*K*0.5;
    }

    //撞左边的墙
    if (this->balls[i].x<=this->balls[i].size){
        this->balls[i].x=this->balls[i].size;//防止速度过快穿过墙
        this->balls[i].vx=-this->balls[i].vx*K*0.5;
    }

    //撞上边的墙
    if (this->balls[i].y>=this->HEIGHT-this->balls[i].size){
        this->balls[i].y=this->HEIGHT-this->balls[i].size;//防止速度过快穿过下墙
        this->balls[i].vy=-this->balls[i].vy*K*0.5;
    }

    //若falling=0，则球还在边界上方未落下
    if (this->balls[i].falling==1){
        if (this->balls[i].y-this->balls[i].size<=this->TOPLINE){//判断越界
            for (int j=0;j<this->balls.size();j++){
                this->gamescore+=this->balls[j].type*2;
            }
            this->status=this->STOP;
            this->Finish->show();
        }
    }else if (this->balls[i].y>this->TOPLINE+this->balls[i].size){
        this->balls[i].falling=1;
    }

    //设置摩擦
    if (this->balls[i].y==this->HEIGHT-balls[i].size){
        if(this->balls[i].vx<this->balls[i].ax){
            this->balls[i].vx=0;
        }
        if(this->balls[i].vx!=0){
            if (this->balls[i].vx<0) {
                this->balls[i].ax=0.1;   //向右摩擦力
            }
            if (this->balls[i].vx>0) {
                balls[i].ax=-0.1;  //向左摩擦力
            }
        }
    }else if (this->balls[i].y<this->HEIGHT-this->balls[i].size){   //x加速度置零
        this->balls[i].ax=0;
    }
}
// combine 合成
auto MainWindow::combine(int i, int j)->void{
    // 创建一个新的球
    Ball b;
    b.initball(this->balls[i].type+1);
    double vi=sqrt(this->balls[i].vx*this->balls[i].vx+this->balls[i].vy*this->balls[i].vy);
    double vj=sqrt(this->balls[j].vx*this->balls[j].vx+this->balls[j].vy*this->balls[j].vy);

    //合成的位置为速度较小的球
    if (vi<vj){
        b.x=b._x=this->balls[i].x;
        b.y=b._y=this->balls[i].y;
    }else {
        b.x=b._x=this->balls[j].x;
        b.y=b._y=this->balls[j].y;
    }

    // 判断是否是最大的球
    if(this->maxBallSize<=b.size){
        this->maxBallSize=b.size;
        switch (b.type){
        case 0:
            this->background=BACKGROUND::TYPE1;
            break;
        case 1:
            this->background=BACKGROUND::TYPE2;
            break;
        case 2:
            this->background=BACKGROUND::TYPE3;
            break;
        case 3:
            this->background=BACKGROUND::TYPE4;
            break;
        case 4:
            this->background=BACKGROUND::TYPE5;
            break;
        case 5:
            this->background=BACKGROUND::TYPE6;
            break;
        case 6:
            this->background=BACKGROUND::TYPE7;
            break;
        default:
            this->background=BACKGROUND::TYPE8;
            break;
        }

        // 重新绘制背景图
        this->repaint();
    }

    //判断是否赢得比赛->合成第7个类型即表示胜利
    if (b.type==7){
        this->status=WIN;
        this->Win->show();
        this->update();
    }

    // 合成的新球的速度为两球速度的平均值
    b.vx=(this->balls[i].vx+this->balls[j].vx)/2.0;
    b.vy=(this->balls[i].vy+this->balls[j].vy)/2.0;
    b.ay=1;
    b.falling=1;

    this->balls[i]=b;     //将合成的新球替换balls[i]
    this->collideWall(i);
    this->balls[j]=this->balls[this->balls.size()-1];
    this->balls.pop_back();   //从balls数组中删除balls[j]
    this->gamescore+=2*this->balls[i].type;
    this->str=QString("score:%1").arg(this->gamescore);
    this->q->setText(str);


}

// collision 碰撞处理
auto MainWindow::collision()->void{
    for (int i=0;i<this->balls.size();i++){
        for (int j=0;j<this->balls.size();j++){
            if (i==j) {
                continue;
            }
            //判断两球是否相邻
            double dx=this->balls[i].x-this->balls[j].x;
            double dy=this->balls[i].y-this->balls[j].y;
            double distance=sqrt(dx*dx+dy*dy);
            double D=this->balls[i].size+this->balls[j].size;
            if (distance>D) continue;
            //两球种类相同则合成
            if (this->balls[i].type==this->balls[j].type){
                this->combine(i,j);
                this->X0=this->balls[i].x;
                this->Y0=this->balls[i].y;
                this->status=this->BOOM;
                this->update();
                this->status=this->START;
                continue;

         if(balls[i].type==1)
            {

QMediaPlayer *bangchan;
                bangchan=new QMediaPlayer;
                QUrl bangchanfile(QUrl::fromLocalFile(":/src/music/1.wav"));
               bangchanfile.setPath(":/src/music/1.wav");

               bangchan->setMedia(QMediaContent(bangchanfile));
               bangchan->play();
              // Back->show();
 // QSound::play("://src/music/1.wav");
                //playSound("://src/music/1.wav");
              /*  QString soundFilePath = QCoreApplication::applicationDirPath() + "/src/music/1.wav";
                QSoundEffect soundEffect1;
                soundEffect1.setSource(QUrl::fromLocalFile(soundFilePath));
                soundEffect1.setVolume(1.0); // 注意：音量通常是0.0到1.0之间的浮点数
                soundEffect1.play();*/
            }
            if(balls[i].type==2)
            {
               QMediaPlayer *leeknow;
                leeknow=new QMediaPlayer;
               QUrl leeknowfile(QUrl::fromLocalFile(":/src/music/2.wav"));
                leeknowfile.setPath(":/src/music/2.wav");
                leeknow->setMedia(QMediaContent(leeknowfile));
               leeknow->play();
                //Back->show();
                 //QSound::play("://src/music/2.wav");
                //playSound("://src/music/2.wav");
              /*  QString soundFilePath = QCoreApplication::applicationDirPath() + "/src/music/2.wavv";
                QSoundEffect soundEffect2;
                soundEffect2.setSource(QUrl::fromLocalFile(soundFilePath));
                soundEffect2.setVolume(1.0); // 注意：音量通常是0.0到1.0之间的浮点数
                soundEffect2.play();*/
            }
            if(balls[i].type==3)
            {
             QMediaPlayer *changbin;
                changbin=new QMediaPlayer;
                 QUrl changbinfile(QUrl::fromLocalFile(":/src/music/3.wav"));
                changbinfile.setPath(":/src/music/3.wav");
                changbin->setMedia(QMediaContent(changbinfile));
                changbin->play();
               // Back->show();
               //  QSound::play("://src/music/3.wav");
                //playSound("://src/music/3.wav");
           /*  QString soundFilePath = QCoreApplication::applicationDirPath() + "/src/music/3.wav";
             QSoundEffect soundEffect3;
             soundEffect3.setSource(QUrl::fromLocalFile(soundFilePath));
             soundEffect3.setVolume(1.0); // 注意：音量通常是0.0到1.0之间的浮点数
             soundEffect3.play();*/
            }
            if(balls[i].type==4)
            {
             QMediaPlayer *hynjin;
                hynjin=new QMediaPlayer;
                QUrl hynjinfile(QUrl::fromLocalFile(":/src/music/4.wav"));
                hynjinfile.setPath(":/src/music/4.wav");
                hynjin->setMedia(QMediaContent(hynjinfile));
                hynjin->play();
               // Back->show();
              /*  QString soundFilePath = QCoreApplication::applicationDirPath() + "/src/music/4.wav";
                QSoundEffect soundEffect4;
                soundEffect4.setSource(QUrl::fromLocalFile(soundFilePath));
                soundEffect4.setVolume(1.0); // 注意：音量通常是0.0到1.0之间的浮点数
                soundEffect4.play();*/
            }
            if(balls[i].type==5)
            {
              QMediaPlayer *han;
                han=new QMediaPlayer;
                 QUrl hanfile(QUrl::fromLocalFile(":/src/music/5.wav"));
                hanfile.setPath(":/src/music/5.wav");
                han->setMedia(QMediaContent(hanfile));
                han->play();
                /*QString soundFilePath = QCoreApplication::applicationDirPath() + "/src/music/5.wav";
                QSoundEffect soundEffect5;
                soundEffect5.setSource(QUrl::fromLocalFile(soundFilePath));
                soundEffect5.setVolume(1.0); // 注意：音量通常是0.0到1.0之间的浮点数
                soundEffect5.play();*/
            }
            if(balls[i].type==6)
            {

               QMediaPlayer *felix;
                felix=new QMediaPlayer;
                 QUrl felixfile(QUrl::fromLocalFile(":/src/music/6.wav"));
                felixfile.setPath(":/src/music/6.wav");
                felix->setMedia(QMediaContent(felixfile));
                felix->play();
               /* QString soundFilePath = QCoreApplication::applicationDirPath() + "/src/music/6.wav";
                QSoundEffect soundEffect6;
                soundEffect6.setSource(QUrl::fromLocalFile(soundFilePath));
                soundEffect6.setVolume(1.0); // 注意：音量通常是0.0到1.0之间的浮点数
                soundEffect6.play();
//Back->show();                //QSound::play("://src/music/6.wav");
                //playSound("://src/music/6.wav");*/
            }
            if(balls[i].type==7)
            {
            QMediaPlayer *seungmin;
                seungmin=new QMediaPlayer;
                QUrl seungminfile(QUrl::fromLocalFile(":/src/music/7.wav"));
                seungminfile.setPath(":/music/7.wav");
                seungmin->setMedia(QMediaContent(seungminfile));
                seungmin->play();
               /* QString soundFilePath = QCoreApplication::applicationDirPath() + "/src/music/7.wav";
                QSoundEffect soundEffect7;
                soundEffect7.setSource(QUrl::fromLocalFile(soundFilePath));
                soundEffect7.setVolume(1.0); // 注意：音量通常是0.0到1.0之间的浮点数
                soundEffect7.play();*/
            }
            if(balls[i].type==8)
            {
            QMediaPlayer *in;
                in=new QMediaPlayer;
                 QUrl infile(QUrl::fromLocalFile(":/src/music/8.wav"));
                infile.setPath(":/src/music/8.wav");
                in->setMedia(QMediaContent(infile));
                in->play();
               /* QString soundFilePath = QCoreApplication::applicationDirPath() + "/src/music/8.wav";
                QSoundEffect soundEffect8;
                soundEffect8.setSource(QUrl::fromLocalFile(soundFilePath));
                soundEffect8.setVolume(1.0); // 注意：音量通常是0.0到1.0之间的浮点数
                soundEffect8.play();*/
            }}
            double vi=sqrt(this->balls[i].vx*this->balls[i].vx+this->balls[i].vy*this->balls[i].vy);
            double vj=sqrt(this->balls[j].vx*this->balls[j].vx+this->balls[j].vy*this->balls[j].vy);
            if (vi>speedlimit||vj>speedlimit){              //若速度过快，强制沿原方向退回一段距离
                double dxi=(this->balls[i]._x-this->balls[i].x)/10.0;
                double dyi=(this->balls[i]._y-this->balls[i].y)/10.0;
                double dxj=(this->balls[j]._x-this->balls[j].x)/10.0;
                double dyj=(this->balls[j]._y-this->balls[j].y)/10.0;
                for (int k=0;k<10&&distance-D<0;k++){
                    this->balls[i].x+=dxi;
                    this->balls[i].y+=dyi;
                    this->balls[j].x+=dxj;
                    this->balls[j].y+=dyj;
                    dx=this->balls[i].x-this->balls[j].x;
                    dy=this->balls[i].y-this->balls[j].y;
                    distance=sqrt(dx*dx+dy*dy+0.0);
                }
            }
            double ex=dx/distance,ey=dy/distance;           //法向单位向量(ex,ey)，方向由j指向i
            if (distance<D){                                //对重叠在一起的球进行位置修正
                double dd=D-distance;
                this->balls[j].x-=dd*ex*this->balls[i].mass/(this->balls[i].mass+this->balls[j].mass);
                this->balls[i].x+=dd*ex*this->balls[j].mass/(this->balls[i].mass+this->balls[j].mass);
                if (this->balls[i].y>this->balls[j].y) {
                    this->balls[j].y-=fabs(dd*ey);
                }else {
                    this->balls[i].y-=fabs(dd*ey);
                }
            }

            double ux=-dy/distance,uy=dx/distance;          //切向单位向量(ux,uy),方向为(ex,ey)逆时针旋转π/2
            //球在两球连线方向上的速度投影为v=(vx,vy)·(ex,ey)
            double v1=ex*this->balls[i].vx+ey*this->balls[i].vy;        //i的法向速度
            double v2=ex*this->balls[j].vx+ey*this->balls[j].vy;        //j的法向速度
            if (v2<v1) continue;//两球擦肩而过，不相撞
            //球在切线方向上的速度投影为v'=(vx,vy)·(ux,uy)
            double v11=ux*this->balls[i].vx+uy*this->balls[i].vy;       //i的切向速度
            double v22=ux*this->balls[j].vx+uy*this->balls[j].vy;       //j的切向速度
            //根据动量守恒和动能定理计算碰撞后两球连线方向上的速度u1和u2,其中K表示动能损失程度
            double m1=this->balls[i].mass,m2=this->balls[j].mass;
            double u1=K*((m1-m2)*v1+2*m2*v2)/(m1+m2);       //i碰撞后法向速度
            double u2=K*((m2-m1)*v2+2*m1*v1)/(m1+m2);       //j碰撞后法向速度
            //最终的速度矢量(vx,vy)=(u1*ex+v11*ux,u1*ey+v11*uy)·(i,j)
            this->balls[i].vx=1*(u1*ex+v11*ux);
            this->balls[i].vy=1*(u1*ey+v11*uy);
            this->balls[j].vx=1*(u2*ex+v22*ux);
            this->balls[j].vy=1*(u2*ey+v22*uy);
        }

    }

}



